Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix($rootScope): correctly propagate async changes after local $digest() #15501

Conversation

gkalpak
Copy link
Member

@gkalpak gkalpak commented Dec 12, 2016

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix.

What is the current behavior? (You can also link to an open issue here)
If an async task is scheduled (via $evalAsync()) on a scope and $digest() happens to be called on another, unrelated scope (local digest), then the asyncQueue will be drained but $rootScope.$digest() will not be called (potentially preventing the changes to propagate correctly through the app).
See #15127.

What is the new behavior (if this is a feature change)?
Angular keeps track on whether $digest() has been called on $rootScope or not and calls $rootScope.$digest() if necessary (even if the asyncQueue has been drained by a local $digest()).

Does this PR introduce a breaking change?
No.

Please check if the PR fulfills these requirements

Other information:
This is a more targeted alternative to #15494.
Fixes #15127.

…st()`

Previously, if an async task was scheduled (via `$evalAsync()`) on a scope and
`$digest()` happened to be called on another, unrelated scope (local digest),
then the `asyncQueue` would be drained but `$rootScope.$digest()` would not be
called (potentially preventing the changes to propagate correctly through the
app).

This commit fixes it by keeping track on whether `$digest()` has been called
on `$rootScope` or not and call `$rootScope.$digest()` if necessary (even if the
`asyncQueue` has been drained by a local `$digest()`).

Fixes angular#15127
Closes angular#15494
@@ -799,6 +799,10 @@ function $RootScopeProvider() {
}
asyncQueue.length = 0;

if (this === $rootScope) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved out of the while dirty loop since it's not necessary for it to be there

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to put this as close as possible to the point where we were certain that the asyncQueue has been fully processed. In 99.9% of the cases it won't make any difference if this is moved out of the look, so I am fine moving it.

@gkalpak
Copy link
Member Author

gkalpak commented Dec 13, 2016

Thinking it over, I think #15494 (even if not perfect) is a better alternative.

@gkalpak gkalpak closed this Dec 13, 2016
@gkalpak gkalpak deleted the fix-rootScope-local-digest-after-evalAsync branch December 13, 2016 22:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Manually calling $digest on a scope prevents $rootScope.$digest from executing for pending $evalAsyncs
3 participants